package com.example.administrator.exkotlin.base

import android.content.Context
import android.content.Intent
import java.lang.StringBuilder

/**
 * Author by lp,on 2020/7/23/023,16:36.
 * 泛型
 * 定义：
 *     class obj<T>{
 *     fun method(parms:T):T{
return parms}
 *     }
 *     方法:
 *      fun <M>method2(parms: M):M{
 *      return parms
}

 */
class Generic<T> {
    fun method(parms: T): T {
        return parms
    }

    //方法上的泛型
    fun <M> method2(parms: M): M {
        return parms
    }

    //泛型的约束
    fun <Y : Number> method3(parms: Y): Y {
        return parms
    }

    /**
     * 泛型的实化
     * 作用：允许在泛型函数中获取到泛型的实际类型
     * 关键字 reified  内联函数inline
     * 使用了内联函数，实际上是替换了泛型执行的代码
     * 定义：inline fun<reified T> getType(){
     * }
     * */
    inline fun <reified T> getType() = T::class.java

    /**
     * 泛型实化的应用
     * 可以用来完成 a is T 、T::class.java等
     * */
    companion object {
        inline fun <reified T> startActivity(context: Context) {
            val intent = Intent(context, T::class.java)
            context.startActivity(intent)
        }

        //进阶，增加一个高阶函数，用于增加Intent中的附带参数
        inline fun <reified T> startActivity(context: Context, block: Intent.() -> Unit) {
            val intent = Intent(context, T::class.java)
            intent.block()
            context.startActivity(intent)
        }

        /**
         * 泛型的协变、逆变
         * 约定：参数列表接收数据的地方，成为in位置，返回值输出数据的地方成为泛型的out位置
         * interface test<T>{
         *  fun method（parm：T）:T
         *  //其中parm 位置为in 位置， ：T 为out位置
         * }
         * 协变： 关键字out
         * class obj<out T>（val data：T）{
         *        fun get():T{
         *        return data
         *        }
         * 不允许对in位置的泛型，再做修改或者赋值，即为协变，例如kotlin中的listof集合
         *
         * 逆变 关键字in
         * 不允许对有返回值，不允许返回泛型，即为逆变，例如kotlin中的Comparable接口
         * */
    }


}